import userDao from "../dao/userDB.js";
import {getUniAccount, randomCaptcha, sendEmail} from "../utils/utils.js";
import sequelize from "../models/initSequelize.js";
import userBaseDao from "../dao/userbaseDB.js";
import {createToken} from "../middleware/JWTToken.js";
import captchaDao from "../dao/captchaDB.js";

/**
 * 注册新账号
 * @param passwordMd5
 * @param name
 * @param email
 * @returns {Promise<string>}
 */
export const signNewAccount = async (passwordMd5, name, email) => {
  let isExistedEmail = await userDao.isExistedByEmail(email);
  if (isExistedEmail) {
    throw new Error("邮箱已经创建账号，请勿重复申请！");
  }
  let account = await getUniAccount();
  const t = await sequelize.transaction();
  try {
    let user = await userDao.addUser(account, passwordMd5, email, t);
    let userBase = await userBaseDao.addUserBaseInfo(account, "", "", "", name, t);
    if (!(user && userBase)) {
      await t.rollback();
      throw new Error("用户创建失败请联系管理员！");
    }
    await t.commit();
  } catch (e) {
    await t.rollback();
    throw new Error("用户创建失败请联系管理员！");
  }
  return account;
};

/**
 * 登录并返回token
 * @param account
 * @param passwordMd5
 * @returns {Promise<string>}
 */
export const loginGetToken = async (account, passwordMd5) => {
  let isExisted = await userDao.isExistedByPassword(account, passwordMd5);
  if (!isExisted) {
    throw new Error("账号密码错误！");
  }
  let token = "";
  try {
    token = await createToken(account);
  } catch (e) {
    throw new Error("登录失败请联系管理员！");
  }
  return token;
};


/**
 * 获取用户基础信息
 * @param account
 * @returns {Promise<*>}
 */
export const getUserBaseInfo = async (account) => {
  let isExisted = await userBaseDao.isExisted(account);
  if (!isExisted) {
    throw new Error('请输入正确的用户账号！');
  }
  return userBaseDao.getUserBaseInfo(account);
};


/**
 * 发送修改密码邮件验证码
 * @param account
 * @returns {Promise<void>}
 */
export const sendEmailToUpdatePWD = async (account) => {
  let isExisted = await userDao.isExisted(account);
  if (!isExisted) {
    throw new Error('请输入正确的账号！');
  }
  let checkSendEmail = await captchaDao.checkSendCode(account);
  if (checkSendEmail) {
    throw new Error('请不要频繁发送验证码！');
  }
  let email = await userDao.getUserEmail(account);
  email = email._email;
  if (!email) {
    throw new Error('请先绑定邮箱！');
  }
  let code = randomCaptcha();
  let updateRes = await captchaDao.updateCode(account, code);
  if (!updateRes[0]) {
    throw new Error('请不要频繁获取验证码！');
  }
  let result = await sendEmail(email, {html: `WuFeng聊天软件--修改密码:<br/>验证码有效期5分钟，保存好验证码，请不要泄露给其他人。<h2>${code}</h2>`});
  if (!result.result) {
    throw new Error('发送失败，请联系管理员！');
  }
};

/**
 * 更新密码
 * @param account
 * @param mailCode
 * @param newPasswordMd5
 * @returns {Promise<void>}
 */
export const updatePWD = async (account, mailCode, newPasswordMd5) => {
  let isExistedCode = await captchaDao.isExistedByCode(account, mailCode);
  if (!isExistedCode) {
    throw new Error('请输入正确的账号和验证码,或重新获取验证码！');
  }
  let isExisted = await userDao.isExisted(account);
  if (!isExisted) {
    throw new Error('请输入正确的账号！');
  }
  let accountPassword = await userDao.isExistedByPassword(account, newPasswordMd5);
  if (accountPassword) {
    throw new Error('请不要输入与原密码相同的密码！');
  }
  const t = await sequelize.transaction();
  try {
    let updateCode = await captchaDao.updateCode(account, mailCode, "0", t);
    let updatePassword = await userDao.updatePassword(account, newPasswordMd5, t);
    // console.log(updatePassword, updateCode);
    if (!(updateCode[0] && updatePassword[0])) {
      await t.rollback();
      throw new Error("修改密码失败请联系管理员！");
    }
    await t.commit();
  } catch (e) {
    await t.rollback();
    throw new Error("修改密码失败请联系管理员！");
  }
};

/**
 * 更新用户基础信息
 * @param account
 * @param avatar
 * @param birth
 * @param signature
 * @param name
 * @returns {Promise<void>}
 */
export const updateUserBaseInfo = async (account, avatar, birth, signature, name) => {
  let isExisted = await userBaseDao.isExisted(account);
  if (!isExisted) {
    throw new Error('请输入正确的用户账号！');
  }
  await userBaseDao.updateUserBaseInfo(account, avatar, birth, signature, name);
};
